package com.sure0000.java8;

import org.junit.Test;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
 *
 * 这种风格将要处理的元素集合看作一种流， 流在管道中传输， 并且可以在管道的节点上进行处理， 比如筛选， 排序，聚合等。
 * 元素流在管道中经过中间操作（intermediate operation）的处理，最后由最终操作(terminal operation)得到前面处理的结果。
 *
 * @author xuyouchang
 * @date 2020/11/3.
 */
public class StreamDemo {

    private static final Long MAX = 10000L;

    /**
     * 串行流：适合存在线程安全问题、阻塞任务、重量级任务，以及需要使用同一事务的逻辑。
     */
    @Test
    public void stream() {
        List<String> stringsSample = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
        List<String> filtered = stringsSample.stream().filter(item -> !item.isEmpty()).collect(Collectors.toList());
        System.out.println(filtered);
    }

    /**
     * 并行流：适合没有线程安全问题、较单纯的数据处理任务。
     */
    @Test
    public void paralleStream() {
        List<String> stringsSample = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
        List<String> filtered = stringsSample.parallelStream().filter(item -> !item.isEmpty()).collect(Collectors.toList());
        System.out.println(filtered);
    }


    /**
     * Collectors 类实现了很多归约操作，例如将流转换成集合和聚合元素。Collectors 可用于返回列表或字符串：
     */
    @Test
    public void collectors() {
        List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
        List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

        System.out.println("筛选列表: " + filtered);
        String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining("|"));
        System.out.println("合并字符串: " + mergedString);
    }

    /**
     * https://www.cnblogs.com/diegodu/p/8794857.html
     * map 对元素进行一一映射操作，将元素转化为Stream对象，而 flatmap 将子stream中的元素拆分到父stream中，
     * 一句话来说：把几个小的list转换到一个大的list。
     *
     * https://www.cnblogs.com/lijingran/p/8727507.html
     * map 将一种类型的值转换为另外一种类型的值。
     * flatmap: 将多个Stream连接成一个Stream，这时候不是用新值取代Stream的值，与map有所区别，这是重新生成一个Stream对象取而代之。
     *
     */
    @Test
    public void mapAndFlatMap() {
        List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
        List<Stream<String>> maplist = strings.stream().map(item->item.split("")).map(Arrays::stream).distinct().collect(Collectors.toList());
        List<String> flatList = strings.stream().map(item->item.split("")).flatMap(Arrays::stream).distinct().collect(Collectors.toList());
        System.out.println(maplist);
        System.out.println(flatList);
    }
}
